package com.wzk.travelspringboot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzk.travelspringboot.common.LogToFile;
import com.wzk.travelspringboot.common.weather.WeatherNowResponse;
import com.wzk.travelspringboot.common.weather.WeatherResponse;
import com.wzk.travelspringboot.common.weather.WeatherSevenDayResponse;
import com.wzk.travelspringboot.common.weather.WeatherSixHourResponse;
import com.wzk.travelspringboot.dto.Result;
import com.wzk.travelspringboot.service.WeatherService;
import com.wzk.travelspringboot.utils.RequestLimitUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.logging.Logger;

/**
 * @Author: WangZiKang
 * @Date: 2025/1/18 11:31
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class WeatherServiceImpl implements WeatherService {

    public static final Logger logger = Logger.getLogger(WeatherServiceImpl.class.getName());

    private final ObjectMapper objectMapper;

    private final StringRedisTemplate stringRedisTemplate;

    @Value("${weather.key}")
    private String key;

    @Value("${weather.nowUrl}")
    private String nowUrl;

    @Value("${weather.perHourUrl}")
    private String perHourUrl;

    @Value("${weather.sevenDayUrl}")
    private String sevenDayUrl;

    @Value("${weather.cityUrl}")
    private String cityUrl;

    private final RequestLimitUtil limitUtil;

    @Override
    public Result now(String cityName) {
        try{
            //限流
            boolean b = limitUtil.reqLimit("now");
            if (!b){
                return Result.failed("请求过于频繁请待会再试....");
            }
            //0.key
            HashMap<String, String> header = new HashMap<>();
            header.put("X-QW-Api-Key",key);
            //1.根据城市名称查询城市的locationId
            HashMap<String, Object> params = new HashMap<>();
            params.put("location",cityName);
            String cityResult = HttpUtil.createGet(cityUrl).addHeaders(header).form(params).execute().body();
            if (cityResult.contains("error") || StrUtil.isBlank(cityResult)){
                return Result.failed("未查询到["+cityName+"]的天气数据");
            }
            //2.解析出结果中的locationId
            WeatherResponse weatherResponse = objectMapper.readValue(cityResult, WeatherResponse.class);
            //3.获取第一个的locationId
            String locationId = weatherResponse.getLocation().get(0).getId();
            //4.拿到locationId查询该城市24小时的天气
            HashMap<String, Object> requestParma = new HashMap<>();
            requestParma.put("location",locationId);
            //5.获取实时天气
            String body = HttpUtil.createGet(nowUrl).addHeaders(header).form(requestParma).execute().body();
            if (StrUtil.isBlank(body) || !body.contains("\"code\":\"200\"")){
                return Result.failed("未查询到[\"+cityName+\"]的天气数据");
            }
            //6.解析天气数据返回
            WeatherNowResponse res = objectMapper.readValue(body, WeatherNowResponse.class);
            return Result.success("数据加载成功",res);
        }catch (Exception e){
            LogToFile.logToFile("now 方法中出现异常："+e,logger,"now_method_err");
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result perHour(String cityName) {
        try{
            //限流
            boolean b = limitUtil.reqLimit("per:hour");
            if (!b){
                return Result.failed("请求过于频繁请待会再试....");
            }
            //1.获取城市的id
            //0.key
            HashMap<String, String> header = new HashMap<>();
            header.put("X-QW-Api-Key",key);
            //1.根据城市名称查询城市的locationId
            HashMap<String, Object> params = new HashMap<>();
            params.put("location",cityName);
            String cityResult = HttpUtil.createGet(cityUrl).addHeaders(header).form(params).execute().body();
            if (cityResult.contains("error") || StrUtil.isBlank(cityResult)){
                return Result.failed("未查询到["+cityName+"]的天气数据");
            }
            //2.解析出结果中的locationId
            WeatherResponse weatherResponse = objectMapper.readValue(cityResult, WeatherResponse.class);
            //3.获取第一个的locationId
            String locationId = weatherResponse.getLocation().get(0).getId();
            //4.拿到locationId查询该城市24小时的天气
            HashMap<String, Object> requestParma = new HashMap<>();
            requestParma.put("location",locationId);
            //5.获取24小时的天气
            String body = HttpUtil.createGet(perHourUrl).addHeaders(header).form(requestParma).execute().body();
            if (StrUtil.isBlank(body) || !body.contains("\"code\":\"200\"")){
                return Result.failed("未查询到["+cityName+"]的天气数据");
            }
            //6.解析数据
            WeatherSixHourResponse res = objectMapper.readValue(body, WeatherSixHourResponse.class);
            //7.删除后6个元素只保留前6个
            res.setHourly(res.getHourly().subList(0,6));
            //8.返回结果
            return Result.success("数据加载成功",res.getHourly());
        }catch (Exception e){
            LogToFile.logToFile("perHour 方法中出现异常："+e,logger,"perHour_method_err");
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result sevenDay(String cityName) {
        try{
            //限流
            boolean b = limitUtil.reqLimit("seven:day");
            if (!b){
                return Result.failed("请求过于频繁请待会再试....");
            }
            //0.key
            HashMap<String, String> header = new HashMap<>();
            header.put("X-QW-Api-Key",key);
            //1.根据城市名称查询城市的locationId
            HashMap<String, Object> params = new HashMap<>();
            params.put("location",cityName);
            String cityResult = HttpUtil.createGet(cityUrl).addHeaders(header).form(params).execute().body();
            if (cityResult.contains("error") || StrUtil.isBlank(cityResult)){
                return Result.failed("未查询到["+cityName+"]的天气数据");
            }
            //2.解析出结果中的locationId
            WeatherResponse weatherResponse = objectMapper.readValue(cityResult, WeatherResponse.class);
            //3.获取第一个的locationId
            String locationId = weatherResponse.getLocation().get(0).getId();
            //4.拿到locationId查询该城市7天的天气
            HashMap<String, Object> requestParma = new HashMap<>();
            requestParma.put("location",locationId);
            //5.查询
            String body = HttpUtil.createGet(sevenDayUrl).addHeaders(header).form(requestParma).execute().body();
            //6.转换成实体类
            WeatherSevenDayResponse res = objectMapper.readValue(body, WeatherSevenDayResponse.class);
            return Result.success(res);
        }catch (Exception e){
            LogToFile.logToFile("sevenDay 方法中出现异常："+e,logger,"sevenDay_method_err");
            throw new RuntimeException(e);
        }
    }
}
